/**************************************************************************************************
	$Header: /pub/cvsroot/mydns/src/util/dumpzone.c,v 1.5 2002/07/29 06:34:02 bboy Exp $
	Outputs zone data in BIND format.

	Copyright (C) 2002  Don Moore <bboy@bboy.net>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at Your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
**************************************************************************************************/

#include "util.h"

char zone[DNS_MAXNAMELEN];										/* Zone name to dump */


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	USAGE
	Display program usage information.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static void
usage(status)
	int status;
{
	if (status != EXIT_SUCCESS)
	{
		fprintf(stderr, _("Try `%s --help' for more information."), progname);
		fputs("\n", stderr);
	}
	else
	{
		printf(_("Usage: %s ZONE"), progname);
		puts("");
		puts(_("Output MyDNS zone in BIND format."));
		puts("");
/*		puts("----------------------------------------------------------------------------78");  */
		puts(_("  -h, --host=HOST      connect to MySQL server at HOST"));
		puts(_("  -p, --password=PASS  password for MySQL (or prompt from tty)"));
		puts(_("  -u, --user=USER      username for MySQL if not current user"));
		puts(_("  -v, --verbose        be more verbose while running"));
		puts(_("      --help           display this help and exit"));
		puts(_("      --version        output version information and exit"));
		puts("");
		printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
	}
	exit(status);
}
/*--- usage() -----------------------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	CMDLINE
	Process command line options.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static void
cmdline(argc, argv)
	int argc;
	char *argv[];
{
	char	*optstr;
	int	optc, optindex;
	struct option const longopts[] =
	{
		{"host",				required_argument,	NULL,	'h'},
		{"password",		optional_argument,	NULL,	'p'},
		{"user",				required_argument,	NULL,	'u'},
		{"verbose",			no_argument,			NULL,	'v'},

		{"help",				no_argument,			NULL,	0},
		{"version",			no_argument,			NULL,	0},

		{NULL, 0, NULL, 0}
	};

	err_stderr = err_plain = 1;
	error_init(argv[0], LOG_USER);							/* Init output routines */
	optstr = getoptstr(longopts);
	while ((optc = getopt_long(argc, argv, optstr, longopts, &optindex)) != -1)
	{
		switch (optc)
		{
			case 0:
				{
					const char *opt = longopts[optindex].name;

					if (!strcmp(opt, "version"))									/* --version */
					{
						printf("%s ("PACKAGE_NAME") "PACKAGE_VERSION"\n", progname);
						puts("\n" PACKAGE_COPYRIGHT);
						puts(_("This is free software; see the source for copying conditions.  There is NO"));
						puts(_("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."));
						exit(EXIT_SUCCESS);
					}
					else if (!strcmp(opt, "help"))								/* --help */
						usage(EXIT_SUCCESS);
				}
				break;
			case 'h':																	/* -h, --host=HOST */
				conf_set(&Conf, "mysql-host", optarg);
				break;
			case 'p':																	/* -p, --password=PASS */
				if (optarg)
				{
					conf_set(&Conf, "mysql-password", optarg);
					memset(optarg, 'X', strlen(optarg));
				}
				else
					conf_set(&Conf, "mysql-password", passinput(_("Enter password")));
				break;
			case 'u':																	/* -u, --user=USER */
				conf_set(&Conf, "mysql-user", optarg);
				break;
			case 'v':																	/* -v, --verbose */
				err_verbose = 1;
				break;
			default:
				usage(EXIT_FAILURE);
		}
	}
}
/*--- cmdline() ---------------------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	DUMP_SOA
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static MYDNS_SOA *
dump_soa(void)
{
	MYDNS_SOA *soa;
	time_t now = time(NULL);

	if (mydns_soa_load(mysql, &soa, zone) != 0)
		Errx("%s: %s", zone, _("error loading SOA record for zone"));
	if (!soa)
		Errx("%s: %s", zone, _("zone not found"));

	printf("$TTL %u\n", soa->ttl);
	printf("; Zone: %s (#%u)\n", soa->origin, soa->id);
	printf("; %.24s\n", ctime(&now));
	printf("$ORIGIN %s\n\n", soa->origin);

	printf("@\tIN SOA\t%s\t%s (\n", soa->ns, soa->mbox);
	printf("\t\t\t\t%-10d\t  ; Serial\n", soa->serial);
	printf("\t\t\t\t%-10d\t  ; Refresh\n", soa->refresh);
	printf("\t\t\t\t%-10d\t  ; Retry\n", soa->retry);
	printf("\t\t\t\t%-10d\t  ; Expire\n", soa->expire);
	printf("\t\t\t\t%-10d\t) ; Minimum\n\n", soa->minimum);

	return (soa);
}
/*--- dump_soa() --------------------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	DUMP_RR_LONG
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static void
dump_rr_long(MYDNS_SOA *soa)
{
	int rrlen, tt;
	char query[BUFSIZ];
	MYSQL_RES *res;
	MYSQL_ROW row;

	rrlen = sqlnum("SELECT MAX(LENGTH(name)) FROM %s WHERE zone=%u", mydns_rr_table_name, soa->id) + 1;
	if (!(tt = rrlen / 8)) tt = 1;

	snprintf(query, sizeof(query),
		"SELECT "MYDNS_RR_FIELDS" FROM %s WHERE zone=%u ORDER BY name,type,aux",
		mydns_rr_table_name, soa->id);

	/* Submit query */
	if (mysql_real_query(mysql, query, strlen(query)) || !(res = mysql_use_result(mysql)))
		return;

	/* Add results to list */
	while ((row = mysql_fetch_row(res)))
	{
		MYDNS_RR *rr;
		char		*type;

		if (!(rr = mydns_parse_rr(row)))
			continue;
		type = mydns_qtype_str(rr->type);

		printf("%s%.*s", rr->name, tt - (int)(strlen(rr->name) / 8), "\t\t\t\t\t\t\t\t\t\t");

		printf("\t%u\tIN %s\t", (rr->ttl < soa->minimum) ? soa->minimum : rr->ttl, type);
		if (strlen(type) < 5)
			putc('\t', stdout);

		if (rr->type == DNS_T_MX)
			printf("%u %s\n", (u_int32_t)rr->aux, rr->data);
		else if (rr->type == DNS_T_TXT)
		{
			register unsigned char *c;
			putc('"', stdout);
			for (c = rr->data; *c; c++)
			{
				if (*c == '"')
					putc('\\', stdout);
				putc(*c, stdout);
			}
			putc('"', stdout);
			putc('\n', stdout);
		}
		else
			printf("%s\n", rr->data);
		mydns_rr_free(rr);		
   }
   mysql_free_result(res);
	printf("\n");
}
/*--- dump_rr_long() ----------------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	MAIN
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
int
main(argc, argv)
	int argc;
	const char *argv[];
{
	MYDNS_SOA *soa;

	bindtextdomain(PACKAGE, LOCALEDIR);
	cmdline(argc, argv);
	load_config();
	db_connect();

	if (optind >= argc)
	{
		Warnx(_("required argument missing"));
		usage(EXIT_FAILURE);
	}

	while (optind < argc)
	{
		strncpy(zone, argv[optind++], sizeof(zone)-2);
		if (LASTCHAR(zone) != '.')
			strcat(zone, ".");
		soa = dump_soa();
		dump_rr_long(soa);
		mydns_soa_free(soa);
	}
 
	return (0);
}
/*--- main() ------------------------------------------------------------------------------------*/

/* vi:set ts=3: */
/* NEED_PO */
